<template>
  <div>
    <vxe-grid ref="xGrid" v-bind="gridOptions" @menu-click="onMenuClick"></vxe-grid>
  </div>
</template>

<script>
export default {
  data() {
    const gridOptions = {
      border: true,
      showOverflow: true,
      keepSource: true,
      mouseConfig: {
        selected: true
      },
      editConfig: {
        trigger: 'dblclick',
        mode: 'cell',
        showStatus: true
      },
      columns: [
        { type: 'seq', width: 70 },
        { field: 'name', title: 'Name', editRender: { name: 'input' } },
        { field: 'nickname', title: 'Nickname', editRender: { name: 'input' } },
        { field: 'age', title: 'Age', editRender: { name: 'input' } },
        { field: 'role', title: 'Role', sortable: true, editRender: { name: 'input' } },
        { field: 'address', title: 'Address', sortable: true, editRender: { name: 'input' } }
      ],
      data: [
        { id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' },
        { id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
        { id: 10003, name: 'Test3', nickname: 'T3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
        { id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: 'Women', age: 23, address: 'Shenzhen' },
        { id: 10005, name: 'Test5', nickname: 'T5', role: 'Develop', sex: 'Women', age: 30, address: 'Shanghai' }
      ],
      menuConfig: {
        body: {
          options: [
            [
              { code: 'CLEAR_CELL', name: '清除值' },
              { code: 'REVERT_CELL', name: '还原值' }
            ],
            [
              {
                name: '插入单行数据',
                children: [
                  { code: 'INSERT_AT_ROW', name: '插入单行' },
                  { code: 'INSERT_NEXT_AT_ROW', name: '插入单行 next' },
                  { code: 'INSERT_AT_EDIT_ROW', name: '插入单行并编辑' },
                  { code: 'INSERT_NEXT_AT_EDIT_ROW', name: '插入单行 next 并编辑' }
                ]
              },
              {
                name: '插入多行数据',
                children: [
                  { code: 'BATCH_INSERT_AT_ROW', name: '插入多行' },
                  { code: 'BATCH_INSERT_NEXT_AT_ROW', name: '插入多行 next' },
                  { code: 'BATCH_INSERT_AT_EDIT_ROW', name: '插入多行并编辑' },
                  { code: 'BATCH_INSERT_NEXT_AT_EDIT_ROW', name: '插入多行 next 并编辑 ' }
                ]
              }
            ],
            [
              {
                name: '删除数据',
                children: [{ code: 'DELETE_ROW', name: '删除行' }]
              }
            ],
            // 新增：合并相关菜单
            [
              {
                name: '合并单元格',
                children: [
                  { code: 'MERGE_RIGHT', name: '向右合并（+1 列）' },
                  { code: 'MERGE_DOWN', name: '向下合并（+1 行）' },
                  { code: 'UNMERGE_CELL', name: '取消当前块合并' },
                  { code: 'CLEAR_ALL_MERGE', name: '清除全部合并' }
                ]
              }
            ]
          ]
        }
      },
      // 记录当前合并块（可持久化）
      mergeCells: []
    };
    return {
      gridOptions
    };
  },
  methods: {
    onMenuClick({ menu, row, column }) {
      if (!menu || !menu.code) return;
      switch (menu.code) {
        case 'MERGE_RIGHT':
          return this.mergeRight({ row, column });
        case 'MERGE_DOWN':
          return this.mergeDown({ row, column });
        case 'UNMERGE_CELL':
          return this.unmergeAtCell({ row, column });
        case 'CLEAR_ALL_MERGE':
          return this.clearAllMerge();
        default:
          break;
      }
    },
    // 向右合并：若已在合并块内则扩展列数 +1，否则创建 1x2 块
    mergeRight({ row, column }) {
      const xGrid = this.$refs.xGrid;
      if (!xGrid || !row || !column) return;
      const ri = xGrid.getRowIndex(row);
      const ci = xGrid.getColumnIndex(column);
      if (ri < 0 || ci < 0) return;

      const cols = xGrid.getColumns ? xGrid.getColumns() : this.gridOptions.columns || [];
      const maxCols = cols.length;
      const hit = this._hitMergeAt(ri, ci);

      if (hit) {
        const newColspan = hit.colIndex + hit.colspan < maxCols ? hit.colspan + 1 : hit.colspan;
        if (newColspan === hit.colspan) return; // 到边界了
        const target = { rowIndex: hit.rowIndex, colIndex: hit.colIndex, rowspan: hit.rowspan, colspan: newColspan };
        this._removeIntersects(target);
        xGrid.setMergeCells([target]);
      } else {
        if (ci + 1 >= maxCols) return; // 右边无单元格
        const target = { rowIndex: ri, colIndex: ci, rowspan: 1, colspan: 2 };
        this._removeIntersects(target);
        xGrid.setMergeCells([target]);
      }
      this.gridOptions.mergeCells = xGrid.getMergeCells();
    },
    // 向下合并：若已在合并块内则扩展行数 +1，否则创建 2x1 块
    mergeDown({ row, column }) {
      console.log('mergeDown', row, column);
      const xGrid = this.$refs.xGrid;
      if (!xGrid || !row || !column) return;
      const ri = xGrid.getRowIndex(row);
      const ci = xGrid.getColumnIndex(column);
      if (ri < 0 || ci < 0) return;

      const maxRows = (this.gridOptions.data || []).length;
      const hit = this._hitMergeAt(ri, ci);
      console.log('ri,ci', ri, ci);
      console.log('hit', hit);
      if (hit) {
        const newRowspan = hit.rowIndex + hit.rowspan < maxRows ? hit.rowspan + 1 : hit.rowspan;
        if (newRowspan === hit.rowspan) return; // 到边界了
        const target = { rowIndex: hit.rowIndex, colIndex: hit.colIndex, rowspan: newRowspan, colspan: hit.colspan };
        this._removeIntersects(target);
        xGrid.setMergeCells([target]);
      } else {
        if (ri + 1 >= maxRows) return; // 下方无单元格
        const target = { rowIndex: ri, colIndex: ci, rowspan: 2, colspan: 1 };
        this._removeIntersects(target);
        xGrid.setMergeCells([target]);
      }
      this.gridOptions.mergeCells = xGrid.getMergeCells();
      console.log('mergeCells', this.gridOptions.mergeCells);
    },
    // 取消包含该单元格的合并块
    unmergeAtCell({ row, column }) {
      const xGrid = this.$refs.xGrid;
      if (!xGrid || !row || !column) return;
      const ri = xGrid.getRowIndex(row);
      const ci = xGrid.getColumnIndex(column);
      if (ri < 0 || ci < 0) return;

      const hit = this._hitMergeAt(ri, ci);
      if (!hit) return;
      xGrid.removeMergeCells([{ rowIndex: hit.rowIndex, colIndex: hit.colIndex }]);
      this.gridOptions.mergeCells = xGrid.getMergeCells();
    },
    // 清除全部合并
    clearAllMerge() {
      const xGrid = this.$refs.xGrid;
      if (!xGrid) return;
      xGrid.clearMergeCells();
      this.gridOptions.mergeCells = [];
    },
    // 命中包含 (ri, ci) 的合并块
    _hitMergeAt(ri, ci) {
      const xGrid = this.$refs.xGrid;
      if (!xGrid || !xGrid.getMergeCells) return null;
      const all = xGrid.getMergeCells() || [];
      for (const m of all) {
        const r0 = m.rowIndex,
          c0 = m.colIndex;
        const r1 = r0 + (m.rowspan || 1) - 1;
        const c1 = c0 + (m.colspan || 1) - 1;
        if (ri >= r0 && ri <= r1 && ci >= c0 && ci <= c1) return m;
      }
      return null;
    },
    // 移除与目标相交的既有合并块，避免冲突
    _removeIntersects(target) {
      const xGrid = this.$refs.xGrid;
      if (!xGrid || !xGrid.getMergeCells) return;
      const all = xGrid.getMergeCells() || [];
      const t = {
        r0: target.rowIndex,
        c0: target.colIndex,
        r1: target.rowIndex + target.rowspan - 1,
        c1: target.colIndex + target.colspan - 1
      };
      const inter = (a, b) => !(a.r1 < b.r0 || a.r0 > b.r1 || a.c1 < b.c0 || a.c0 > b.c1);
      const toRemove = [];
      for (const m of all) {
        const r = { r0: m.rowIndex, c0: m.colIndex, r1: m.rowIndex + m.rowspan - 1, c1: m.colIndex + m.colspan - 1 };
        if (inter(t, r)) toRemove.push({ rowIndex: m.rowIndex, colIndex: m.colIndex });
      }
      if (toRemove.length) xGrid.removeMergeCells(toRemove);
    }
  }
};
</script>
